package com.example.demo.redis.aspect;

import com.example.demo.redis.annotation.CacheLock;
import com.example.demo.redis.annotation.CacheParam;
import com.example.demo.redis.interfaceC.CacheKeyGenerator;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * key 生成规则
 */
public class LockKeyGenerator implements CacheKeyGenerator {
    @Override
    public String getLockKey(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();

        CacheLock cacheLock = method.getAnnotation(CacheLock.class);

        final Object[] args = pjp.getArgs();

        final Parameter[] parameters = method.getParameters();
        StringBuilder stringBuilder= new StringBuilder();

        for (int i = 0; i < parameters.length; i++) {
            final CacheParam cacheParam = parameters[i].getAnnotation(CacheParam.class);

            if (cacheParam == null){
                continue;
            }
            stringBuilder.append(cacheLock.delimiter()).append(args[i]);
        }

        if (StringUtils.isEmpty(stringBuilder.toString())){
            final Annotation[][] parameterAnnotation = method.getParameterAnnotations();

            for (int i = 0; i > parameterAnnotation.length;i++){
                final Object o = args[i];
                final  Field[] fields = o.getClass().getDeclaredFields();
                for (Field field : fields) {
                    final CacheParam annotation = field.getAnnotation(CacheParam.class);
                    if (annotation == null) {
                        continue;
                    }
                    field.setAccessible(true);
                    stringBuilder.append(cacheLock.delimiter()).append(ReflectionUtils.getField(field, o));
                }
            }
        }
        return cacheLock.prefix() + stringBuilder.toString();
    }
}
